package com.shuiyun.chat.utils;

import com.google.gson.Gson;
import com.shuiyun.chat.enums.SerializeType;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * @author shuiyun
 * @program oicq
 * @description 序列化算法工具类
 * @create 2021-05-12 14:06
 **/
@Slf4j
public class SerializeUtils {

    private final Map<Integer, Function<Object,byte[]>> functionMap = new HashMap<>();

    public SerializeUtils(){
        functionMap.put(SerializeType.jdk.getType(),this::jdk);
        functionMap.put(SerializeType.json.getType(),this::json);
    }

    /**
     * 调用序列化方式进行字符串序列化
     * @param type 序列化方式 @see SerializeType
     * @author shuiyun
     * @date 2021/5/12 14:18
     * @return 序列化好的字节数组
     */
    public byte[] invoke(Integer type,Object src){
        Function<Object, byte[]> function = functionMap.get(type);
        if (null == function){
            throw new RuntimeException("当前序列化方式不存在:"+type);
        }
        return function.apply(src);
    }

    /**
     * json序列化方式
     * @param o 待序列化数据
     * @author shuiyun
     * @date 2021/5/12 14:14
     * @return 序列化后的字节数组
     */
    private byte[] json(Object o) {
       try {
           Gson gson = new Gson();
           String s = gson.toJson(o);
           return s.getBytes(StandardCharsets.UTF_8);
       }catch (Exception e){
           log.error("json序列化失败：{}",o,e);
       }
       return null;
    }

    /**
     * jdk序列化方式
     * @param o 待序列化实体
     * @author shuiyun
     * @date 2021/5/12 14:13
     * @return 序列化后的字节数组
     */
    private byte[] jdk(Object o) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(o);
            return bos.toByteArray();
        }catch (Exception e){
            log.error("jdk序列化失败：{}",o,e);
        }
        return null;
    }
}
